package ide.ccf.ccproject.data;

import ide.ccf.ccproject.common.Utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
/**
 * 生成filelist文件
 *
 */
public class GenerateFilelist {
	protected int file_count;
	protected int dir_count;
	protected int link_count;
	protected long total;
	protected String strPath;
	/**
	 * 构造函数
	 * @throws IOException 
	 */
	public GenerateFilelist(String path) throws IOException
	{
		file_count = 0;
		dir_count = 0;
		link_count = 0;
		strPath = path;
		total = 0;
		generateCPK(path);
		setFile(path);
	}
	
	private void setFile(String path) throws IOException {
		Utils.generalCPK(path);
		generateFile(path);
		FileOutputStream fos=new FileOutputStream(new File(strPath + "/CPK/filelist"));
		OutputStreamWriter osw=new OutputStreamWriter(fos, "UTF-8");
		BufferedWriter bw=new BufferedWriter(osw);
		searchFolder(path, bw );
		String content = "I," + file_count + "," + dir_count + ","   + link_count + "," + total;
		bw.write(content + "\t\n");
		bw.close();
		osw.close();
		fos.close();
	}
	
	private void searchFolder(String path, BufferedWriter bw) throws IOException
	{
		File file = new File(path);
		File[] tempList = file.listFiles();
		//System.out.println("该目录下对象个数："+tempList.length);
		for (int i = 0; i < tempList.length; i++) {
			   if (tempList[i].isFile()) {
				   file_count += 1;
				   total += tempList[i].length();
				   String subPath = tempList[i].toString().substring(strPath.length()+1,  tempList[i].toString().length());
				   //System.out.println("F,"+ "/" + subPath+"," +  tempList[i].length() + ",0777," + new Date().getTime() + "," + stringMD5(tempList[i].toString()) );
				   String content = "F,"+ "/" + subPath+"," +  tempList[i].length() + ",0777," + new Date().getTime() + "," + stringMD5(tempList[i].toString()) ;
				   bw.write(content + "\t\n");
			
			   } else if(isSymlink(tempList[i]))
				    {
					    link_count += 1;   
				    }

			   if (tempList[i].isDirectory() && !tempList[i].toString().equals(path + "/CPK")) {
				    dir_count += 1;
				    //System.out.println("文件夹："+tempList[i]);
				    String subPath = tempList[i].toString().substring(strPath.length()+1,  tempList[i].toString().length());
				    //System.out.println("D,"+ "/" + subPath+","+tempList[i].length()+",0777,"+ new Date().getTime());
				    String content = "D,"+ "/" + subPath+","+tempList[i].length()+",0777,"+ new Date().getTime();
					bw.write(content + "\t\n");
				    searchFolder(tempList[i].toString(), bw);
			   }
		}
	}
	
	/**
	 * 判断文件是否是链接文件
	 * 这种判断方式的依据就是，如果是链接文件（软连接、硬链接），
	 * 那么getCanonicalFile和getAbsoluteFile的返回值是不一样的。否则一样。
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static boolean isSymlink(File file) throws IOException {  
        if (file == null)  
            throw new NullPointerException("File must not be null");  
        File canon;  
        if (file.getParent() == null) {  
            canon = file;  
        } else {  
            File canonDir = file.getParentFile().getCanonicalFile();  
            canon = new File(canonDir, file.getName());  
        }  
        return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());  
    } 
	
	//创建Filelist文件
	private void generateFile(String path) throws IOException{
		File f = new File(path + "/CPK/filelist");
		if(!f.exists())
			f.createNewFile();
	}

	private void generateCPK(String path) {
		File f = new File(path+"/CPK");
		//如果文件夹不存在则创建
		if(!f.exists() && !f.isDirectory())
			f.mkdir();
	}

	/**
	 * 实现MD5加密, 获取加密后的字符串
	 * @param pw
	 * @return
	 */
	public static String stringMD5(String pw) {
		  try { 
		        // 拿到一个MD5转换器（如果想要SHA1参数换成”SHA1”） 
		        MessageDigest messageDigest =MessageDigest.getInstance("MD5"); 
		        // 输入的字符串转换成字节数组 
		        byte[] inputByteArray = pw.getBytes(); 
		        // inputByteArray是输入字符串转换得到的字节数组 
		        messageDigest.update(inputByteArray); 
		        // 转换并返回结果，也是字节数组，包含16个元素 
		        byte[] resultByteArray = messageDigest.digest(); 
		        // 字符数组转换成字符串返回 
		        return byteArrayToHex(resultByteArray); 
		     } catch (NoSuchAlgorithmException e) { 
		        return null; 
		     } 
		 }
	
	public static String byteArrayToHex(byte[] byteArray) { 
        // 首先初始化一个字符数组，用来存放每个16进制字符 
        char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'a','b','c','d','e','f' }; 
        // new一个字符数组，这个就是用来组成结果字符串的（解释一下：一个byte是八位二进制，也就是2位十六进制字符（2的8次方等于16的2次方）） 
        char[] resultCharArray =new char[byteArray.length * 2]; 
        // 遍历字节数组，通过位运算（位运算效率高），转换成字符放到字符数组中去 
        int index = 0;
        for (byte b : byteArray) { 
           resultCharArray[index++] = hexDigits[b>>> 4 & 0xf]; 
           resultCharArray[index++] = hexDigits[b& 0xf]; 
        }
        // 字符数组组合成字符串返回 
        return new String(resultCharArray); 
    }
	
}
